home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / TCL1 / GRAPH_FO / (GRAPH / CGRAPHTE / CGRAPHPA.C < prev    next >
Text File  |  1991-06-18  |  12KB  |  467 lines

  1. /******************************************************************************
  2.     CGraphPane.c
  3.  
  4.     SUPERCLASS = CFontorama.c
  5.  
  6.     This Pane uses some of the Prepare Class Library modifications: WViewTemp()
  7.     and implements all necessary modifications to be PCL compatible. If you
  8.     have installed the Prepare TCL modifications, you can #define __PCL__.
  9.     I have included the code to bypass this.
  10.  
  11.     Copyright ⌐ 1991 Maarten Meijer. All rights reserved.
  12.         CIS 100016,1764; FidoNet 2:512/114
  13. *******************************************************************************/
  14.  
  15. /* defines */
  16. /* #define __PCL__ */    /* see above */
  17.  
  18. /* includes */
  19. #include <Global.h>
  20. #include <Constants.h>
  21. #include <Commands.h>
  22. #include <CBartender.h>
  23. #include <CDocument.h>
  24. #include <TBUtilities.h>
  25. #include <Commands.h>
  26. #include <CError.h>
  27.  
  28. #include "GraphCommands.h"
  29. #include "CGraphPane.h"
  30.  
  31. #include "CMoveTask.h"
  32. #include "CLinkTask.h"
  33. #include "CSelRectTask.h"
  34.  
  35.  
  36. /*** Global Variables ***/
  37. extern CBartender *        gBartender;
  38. extern short            gClicks;
  39.  
  40. /* methods */
  41. /******************************************************************************
  42.  IGraphPane
  43.  
  44.         Initialize a GraphPane object
  45.  ******************************************************************************/
  46.  
  47. void    CGraphPane::IGraphPane(
  48.     CView            *anEnclosure,
  49.     CBureaucrat        *aSupervisor,
  50.     short            aWidth,
  51.     short            aHeight,
  52.     short            aHEncl,
  53.     short            aVEncl,
  54.     SizingOption    aHSizing,
  55.     SizingOption    aVSizing)
  56. {
  57.     Point    grid;
  58.     Rect    bounds;
  59.     CPanorama::IPanorama(anEnclosure, aSupervisor,
  60.                         aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  61.     SetWantsClicks(true);    /* a CView method */
  62.     TextFont(geneva);        /* allows three digits or letters */
  63.     TextSize(9);
  64.  
  65.     SetPt(&grid, 40, 40);    /* the Grid */
  66.     itsGraph = new(Graph);
  67.     itsGraph->IGraph(this, (grHAlign | grVAlign) , grid);
  68. }
  69.  
  70. /******************************************************************************
  71.  IViewTemp {OVERRIDE}
  72.  
  73.         Initialize a Panorama using a template
  74.  ******************************************************************************/
  75. void    CGraphPane::IViewTemp(CView *anEnclosure, CBureaucrat *aSupervisor,
  76.                             Ptr viewData) {
  77.     register GraphPaneTempP    p;
  78.     short    fontID;
  79.  
  80.     p = (GraphPaneTempP) viewData;        /* Initialize superclass            */
  81.     inherited::IViewTemp(anEnclosure, aSupervisor, (Ptr) &p->sPanoramaTemp);
  82.  
  83.     GetFNum(&(p->textFName), &fontID);     /* add own variables */
  84.  
  85.     if( RealFont(fontID, p->textSize) ) {
  86.         TextFont(fontID);
  87.         TextSize(p->textSize);
  88.         TextFace(p->textFace);
  89.         }
  90.     else {
  91.         TextFont(geneva);
  92.         TextSize(9);
  93.         TextFace(0);
  94.         }
  95.  
  96.     itsGraph = new(Graph);
  97.     itsGraph->IGraph(this, p->flags , p->theGrid);
  98.     }
  99.  
  100. /******************************************************************************
  101.  WViewTemp {OVERRIDE}
  102.  
  103.         Write the template data for a Panorama.
  104.         This method is include to allow use with the Prepare() TCL Update
  105.         (vol 1, issue 3)
  106.  ******************************************************************************/
  107. void    CGraphPane::WViewTemp(Ptr viewData) {
  108.     register GraphPaneTempP    p;
  109.     register GrafPtr        grafPtr;
  110.     short    fontID;
  111.  
  112.     p = (GraphPaneTempP) viewData;        /* Set superclass template data        */
  113. #ifdef __PCL__
  114.     inherited::WViewTemp((Ptr) &p->sPanoramaTemp);
  115. #else
  116.     /* CPanorama.c + PCL mods */    /* Set template from instance vars    */
  117.     ((PanoramaTempP)p)->bounds = bounds;
  118.     ((PanoramaTempP)p)->hScale = hScale;
  119.     ((PanoramaTempP)p)->vScale = vScale;
  120.     ((PanoramaTempP)p)->position = position;
  121.  
  122.     /* CPane.c + PCL mods */        /* Set template from instance vars    */
  123.     ((PaneTempP)p)->width = width;
  124.     ((PaneTempP)p)->height = height;
  125.     ((PaneTempP)p)->hEncl = hEncl;
  126.     ((PaneTempP)p)->vEncl = vEncl;
  127.     ((PaneTempP)p)->hSizing = hSizing;
  128.     ((PaneTempP)p)->vSizing = vSizing;
  129.     ((PaneTempP)p)->autoRefresh = autoRefresh;
  130.     ((PaneTempP)p)->printClip = printClip;
  131.  
  132.     /* CPane.c + PCL mods */        /* Set template from instance vars    */
  133.     ((ViewTempP)p)->visible = visible;
  134.     ((ViewTempP)p)->active = active;
  135.     ((ViewTempP)p)->wantsClicks = wantsClicks;
  136. #endif
  137.     /*
  138.      *    add own variables
  139.      */
  140.     itsGraph->GetGrid(&p->theGrid);
  141.     p->flags = itsGraph->_flags;
  142.  
  143.     grafPtr = GetMacPort();
  144.     GetFontName(grafPtr->txFont, &(p->textFName));
  145.     p->textSize = grafPtr->txSize;    /* ???? */
  146.     p->textFace = grafPtr->txFace;    /* ???? */
  147.     }
  148.  
  149. /******************************************************************************
  150.  GetTempSize {OVERRIDE}
  151.  
  152.         Get the size of the template data for a Panorama.
  153.         This method is include to allow use with the Prepare() TCL Update
  154.         (vol 1, issue 3)
  155.  ******************************************************************************/
  156. long    CGraphPane::GetTempSize() {
  157.     return (long) sizeof(GraphPaneTemp);
  158.     }
  159.  
  160. void CGraphPane::SaveDefault() {
  161.     Handle                    h;
  162.     long                    size;
  163.     short                    refNum;
  164.     Point                    temp, saved;
  165.  
  166.     saved.h = saved.v = 0;        /* set the scroll position to zero before */
  167.     GetPosition(&temp);            /* saving... */
  168.     SetPosition(saved);
  169.  
  170.     h = GetResource('GrPn', 128);
  171.     CheckResource( h );
  172.     refNum = HomeResFile(h);
  173.     size = GetTempSize();
  174.     SetHandleSize(h, size);
  175.     MoveHHi(h);
  176.     HLock(h);
  177.     WViewTemp( (Ptr) *h );
  178.     HUnlock(h);
  179.     ChangedResource(h);
  180.     WriteResource(h);
  181.     UpdateResFile(refNum);
  182.  
  183.     SetPosition(temp);            /* restore the saved scroll position */
  184.     }
  185.  
  186. void    CGraphPane::Dispose() {
  187.     itsGraph->Dispose();
  188.     inherited::Dispose();
  189.     }
  190.  
  191. /******************************************************************************
  192.  Draw {OVERRIDE}
  193.  
  194.         Draw the contents of the Pane. The area parameter, specified in
  195.         the pane's Frame coordinates, indicates the portion of the Pane
  196.         which needs to be drawn.
  197.  ******************************************************************************/
  198.  
  199. void    CGraphPane::Draw(Rect        *area)
  200. {
  201.     RgnHandle    rh;
  202.     Rect        r = *area;
  203.  
  204.     rh = NewRgn();
  205.     GetClip(rh);    /* save current clip region */
  206.  
  207.     ClipRect(&r);
  208.  
  209.     itsGraph->Draw(&r);
  210.  
  211.     SetClip(rh);    /* restore the clip region */
  212.     DisposeRgn(rh);
  213. }
  214.  
  215. void    CGraphPane::DoCommand(long theCommand) {
  216.  
  217.     switch(theCommand) {
  218.  
  219.         case cmdOptions:
  220.             itsGraph->SetOptions();
  221.             break;
  222.  
  223.  
  224.         case cmdSetDefault:
  225.             SaveDefault();
  226.             break;
  227.  
  228.  
  229.         case cmdDeselectAll:
  230.             Prepare();
  231.             itsGraph->Deselect();    /* deselect vertexes only for now */
  232.             break;
  233.         case cmdInstructions:
  234.             Prepare();
  235.             DrawINST(128);
  236.             break;
  237.         default:
  238.             inherited::DoCommand(theCommand);
  239.             break;
  240.         }
  241.     }
  242.  
  243. void    CGraphPane::UpdateMenus() {
  244.     gBartender->EnableCmd(cmdDeselectAll);
  245.     gBartender->EnableCmd(cmdInstructions);
  246.     gBartender->EnableCmd(cmdSetDefault);
  247.     gBartender->EnableCmd(cmdOptions);
  248.  
  249.     gBartender->EnableCmd(cmdFont);    /* since hierarchical */
  250.     gBartender->EnableCmd(cmdSize);
  251.  
  252.     inherited::UpdateMenus();
  253.     }
  254.  
  255. /******************************************************************************
  256.      DoClick {OVERRIDE}
  257.  
  258.         Respond to a mouse click within the view.
  259.         All communication with the Graph is via Tasks, either CMouseTasks or
  260.         CTasks. MouseTasks are generalized for Graphs in the class CGraphTask.
  261.         The following (undoable) actions can be performed:
  262.  
  263.             Adding a Vertex
  264.             Removing a Vertex
  265.             Adding an Edge (=linking two vertices)
  266.             Removing an Edge
  267.  
  268.             Selecting a Vertex or rectangle
  269.             Continuing a selection (with the shift key)
  270.  
  271.             Moving the selection (with the option key)
  272.  
  273.             Cutting, Copying or Pasting a selection.
  274.  
  275.  ******************************************************************************/
  276. void    CGraphPane::DoClick(
  277.     Point        hitPt,
  278.     short        modifierKeys,
  279.     long        when)
  280. {
  281.     Point            displacement;
  282.     Point            newCenter;
  283.     Rect            bounds, area1, area2;
  284.     RgnHandle        dragRgn;
  285.     CGraphTask *    task = NULL;
  286.     short            taskType = 0;
  287.     GrVertex *        thisVertex = NULL;
  288.     GrEdge *        thisEdge = NULL;
  289.     GrVertex *        fromVertex, *toVertex;
  290.  
  291.     itsSupervisor->Notify(NULL);        /* Clear old task */
  292.  
  293.     thisVertex = (GrVertex *)itsGraph->FindVertex(hitPt);
  294.     if(thisVertex == NULL)
  295.         thisEdge = (GrEdge *)itsGraph->FindEdge(hitPt);
  296.  
  297.     if(    ((thisVertex == NULL) && (thisEdge == NULL )) ) {
  298.         if( !(modifierKeys & shiftKey) )
  299.             itsGraph->Deselect();
  300.         task = new( CSelRectTask );
  301.         taskType = kNoUndoTASK;
  302.         }
  303.  
  304.     if((modifierKeys & optionKey) && (thisVertex != (GrVertex *)NULL)) {
  305.         if( !(modifierKeys & shiftKey) )
  306.             itsGraph->Deselect();
  307.         if( thisVertex->Track() != 0 ) {
  308.             thisVertex->Select();
  309.             SelectConnected();
  310.             }
  311.         }
  312.     else if(modifierKeys & cmdKey) {
  313.         itsGraph->Deselect();    /* group removal only with menu ?? */
  314.         if(thisVertex != NULL) {
  315.             itsGraph->RemoveVertex(thisVertex, TRUE);
  316.             }
  317.         else if(thisEdge != NULL) {
  318.             itsGraph->RemoveEdge(thisEdge, TRUE);
  319.             }
  320.         else {
  321.             itsGraph->AddVertex(hitPt, TRUE);
  322.             }
  323.         }
  324.     else {        /* NO modifier keys╔ */
  325.         if(gClicks >= 2) {
  326.             if(thisVertex != (GrVertex *)NULL) {
  327.                 Rect    r1, r2;
  328.                 Point    p, offset = {0,0};
  329.                 p = thisVertex->center;
  330.                 thisVertex->Select();
  331.                 thisVertex->Draw();
  332.                 SetRect(&r1, p.h, p.v, p.h, p.v);
  333.                 GetFrame(&r2);
  334.                 LocalToGlobal(&offset);
  335.                 OffsetRect(&r2, offset.h, offset.v);
  336.                 OffsetRect(&r1, offset.h, offset.v);
  337.                 ZoomRect(&r1, &r2, true, 1L);
  338.                 }
  339.             else if(thisEdge == (GrEdge *)NULL)
  340.                 itsGraph->AddVertex(hitPt, TRUE);
  341.             }
  342.         else {
  343.             if(thisVertex != (GrVertex *)NULL) {
  344.                 if( thisVertex->Selected() ) {
  345.                     task = new( CMoveTask );
  346.                     taskType = kMoveTASK;
  347.                     }
  348.                 else if( thisVertex->Track() == 0 ) {
  349.                     if(!(modifierKeys & shiftKey))
  350.                         itsGraph->Deselect();
  351.                     task = new( CLinkTask );
  352.                     taskType = kLinkTASK;
  353.                     }
  354.                 else {
  355.                     if(!(modifierKeys & shiftKey))
  356.                         itsGraph->Deselect();
  357.                     thisVertex->ToggleNode(TRUE);
  358.                     }
  359.                 }
  360.             else if(thisEdge != (GrEdge *)NULL) {
  361.                 if(thisEdge->Track() != 0) {
  362.                     if(!(modifierKeys & shiftKey))
  363.                         itsGraph->Deselect();
  364.                     thisEdge->fromVertex->ToggleNode(TRUE);
  365.                     thisEdge->toVertex->ToggleNode(TRUE);
  366.                     }
  367.                 }
  368.             }
  369.  
  370.         }
  371.  
  372.     if(task) {
  373.         task->IGraphTask(taskType, this, itsGraph, hitPt);
  374.         Prepare();
  375.         GetBounds(&bounds);
  376.         /*
  377.          * the EndTracking method decides on the Do() and Notify()
  378.          */
  379.         TrackMouse(task, hitPt, &bounds);
  380.         }
  381.  
  382.     ((CDocument *)itsSupervisor)->dirty = TRUE;
  383.     }
  384.  
  385.  
  386. /******************************************************************************
  387.  HitSamePart {OVERRIDE}
  388.  
  389.         Check whether two points hit the same part of the view.
  390.  ******************************************************************************/
  391.  
  392. Boolean        CGraphPane::HitSamePart(
  393.     Point            pointA,
  394.     Point            pointB)
  395. {
  396.     GrVertex    *vertex;
  397.     GrEdge        *edge;
  398.     register short    delta;
  399.  
  400.     if((vertex = itsGraph->FindVertex(pointA)) != NULL)
  401.         return vertex->PtInNode(pointB);
  402.     else if((edge = itsGraph->FindEdge(pointA)) != NULL)
  403.         return edge->PtInNode(pointB);
  404.     else if( ( (delta = (pointA.h - pointB.h)) < REASONABLY_CLOSE &&
  405.                 delta > -(REASONABLY_CLOSE) ) &&
  406.                 ( (delta = (pointA.v - pointB.v)) < REASONABLY_CLOSE &&
  407.                 delta > -(REASONABLY_CLOSE) ) )
  408.         return true;
  409.     return false;
  410. }
  411.  
  412. /******************************************************************************
  413. PrepareToPrint {OVERRIDE}
  414.  
  415.         Set up the proper text font & size as well
  416. *******************************************************************************/
  417. void        CGraphPane::PrepareToPrint()
  418. {
  419.     CPane::PrepareToPrint();
  420.     TextFont(times);        /* allows three digits or letters */
  421.     TextSize(9);
  422.     }
  423.  
  424. /******************************************************************************
  425.  AdjustCursor {OVERRIDE}
  426.  
  427.         Adjust the shape of the cursor according the position of the mouse.
  428.  ******************************************************************************/
  429.  
  430. void    CGraphPane::AdjustCursor(
  431.     Point        where,                    /* Mouse location in Window coords    */
  432.     RgnHandle    mouseRgn)                /* Region containing the mouse        */
  433. {
  434.     extern    CursHandle    gCrossCursor, gGrabCursor;
  435.  
  436.         SetCursor(*gCrossCursor);
  437. }
  438.  
  439.  
  440. /******************************************************************************
  441.  ScrollToSelection {OVERRIDE}
  442.  
  443.         Scroll a Panorama so that the current selection is visible within
  444.         the frame.
  445.  ******************************************************************************/
  446.  
  447. void    CGraphPane::ScrollToSelection()
  448. {
  449. }
  450.  
  451. /******************************************************************************
  452.     SelectConnected
  453. *******************************************************************************/
  454. static    void    SelConnect(GrEdge *this) {
  455.     if( this->fromVertex->Selected() ) {
  456.         this->toVertex->Select();
  457.         this->toVertex->Draw();
  458.         }
  459.     if( this->toVertex->Selected() ) {
  460.         this->fromVertex->Select();
  461.         this->fromVertex->Draw();
  462.         }
  463.     }
  464.  
  465. void    CGraphPane::SelectConnected() {
  466.     itsGraph->edgeList->DoForEach(SelConnect);
  467.     }